package com.sqfw.project.wpReport.service.impl;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import cn.hutool.core.thread.ThreadUtil;
import com.sqfw.common.exception.base.BaseException;
import com.sqfw.common.utils.StringUtils;
import com.sqfw.project.system.domain.SysDept;
import com.sqfw.project.system.mapper.SysDeptMapper;
import com.sqfw.project.wp.domain.WpBackInfo;
import com.sqfw.project.wp.domain.WpHandleLog;
import com.sqfw.project.wp.domain.WpInfo;
import com.sqfw.project.wp.domain.WpVisitInfo;
import com.sqfw.project.wp.mapper.WpBackInfoMapper;
import com.sqfw.project.wp.mapper.WpHandleLogMapper;
import com.sqfw.project.wp.mapper.WpInfoMapper;
import com.sqfw.project.wp.mapper.WpVisitInfoMapper;
import com.sqfw.project.wpReport.domain.WpHoliday;
import com.sqfw.project.wpReport.mapper.WpHolidayMapper;
import com.sqfw.project.wpReport.service.IWpInfoDeptService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sqfw.project.wpReport.domain.WpInfoExamine;
import com.sqfw.project.wpReport.service.IWpInfoExamineService;

/**
 * 三级承办单位绩效考核计分统计Service业务层处理
 *
 * @author lx
 * @date 2023-07-21
 */
@Slf4j
@Service
public class WpInfoExamineServiceImpl implements IWpInfoExamineService {

    @Autowired
    private WpInfoMapper wpInfoMapper;

    @Autowired
    private WpHandleLogMapper wpHandleLogMapper;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private WpVisitInfoMapper wpVisitInfoMapper;

    @Autowired
    private IWpInfoDeptService wpInfoDeptService;

    @Autowired
    private WpHolidayMapper wpHolidayMapper;

    @Autowired
    private WpBackInfoMapper wpBackInfoMapper;

    //三级承办单位顶级 pid  与数据库数据对应  三级承办单位
    private static final Long sysDeptPid = 1L;

    private static final Integer dayTen = 10;

    @Override
    public List<WpInfoExamine> getWpInfoExamineList(WpInfoExamine wpInfoExamine) {


        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        long year = calendar.get(Calendar.YEAR);
        WpHoliday wpHoliday = new WpHoliday();
        wpHoliday.setYearid(year);
        List<WpHoliday> wpHolidays = wpHolidayMapper.selectWpHolidayList(wpHoliday);


        List<String> dates = wpHolidays.stream()
                .map(WpHoliday::getDtime)
                .map(simpleDateFormat::format)
                .collect(Collectors.toList());

        List<SysDept> depts = new ArrayList<>();


        if (StringUtils.isEmpty(wpInfoExamine.getDeptPid())){
            SysDept dept = new SysDept();
            dept.setParentId(sysDeptPid);
            //获取三级承办单位下面的  中心  部门  处室  区县

            List<SysDept> sysDepts = sysDeptMapper.selectDeptList(dept);
            List<Long> parentIds = sysDepts.stream().map(SysDept::getDeptId).collect(Collectors.toList());
            //获取所有承办单位集合
            List<SysDept> sysDeptList = sysDeptMapper.selectDeptListByParentIds(parentIds);
            depts.addAll(sysDeptList);
        }else {
            SysDept sysDept = new SysDept();
            sysDept.setDeptName(wpInfoExamine.getDeptPid());
            SysDept anElse = sysDeptMapper.selectDeptList(sysDept).stream().findAny().orElse(null);
            if (anElse!=null){
                sysDept.setDeptName(null);
                sysDept.setDeptId(anElse.getDeptId());
                List<SysDept> sysDeptList = sysDeptMapper.selectDeptList(sysDept);
                depts.addAll(sysDeptList);

            }

        }
        //查询不到部门则直接返回
        if (depts.size()==0){
            return new ArrayList<WpInfoExamine>();
        }


        //获取三级承办部门id集合
        List<String> deptLevel2s = depts.stream()
                .map(SysDept::getDeptId)
                .map(String::valueOf)
                .collect(Collectors.toList());
        wpInfoExamine.setDeptLevel2s(deptLevel2s);
        //分配承办单位工单数
        WpHandleLog wpHandleLogDept = new WpHandleLog();
        wpHandleLogDept.setDeptLevel2s(deptLevel2s);
        wpHandleLogDept.setBegainTime(wpInfoExamine.getBegainTime());
        wpHandleLogDept.setEndTime(wpInfoExamine.getEndTime());
        wpHandleLogDept.setNextState("承办单位处理");
        wpHandleLogDept.setScidType(wpInfoExamine.getScidType());
        List<WpHandleLog> wpHandleLogList = wpHandleLogMapper.selectWpidListByDeptIdAndScidType(wpHandleLogDept);

        List<WpInfoExamine> wpInfoExamines = new ArrayList<>();


        //初始化线程数量
        CountDownLatch countDownLatch= ThreadUtil.newCountDownLatch(depts.size());
        for (SysDept sysDept : depts) {
            ThreadUtil.execute(()->{
                //回访查询
                WpVisitInfo visitInfo = new WpVisitInfo();
                //不使用回访时间，使用流转时间内的工单
//                visitInfo.setBegainTime(wpInfoExamine.getBegainTime());
//                visitInfo.setEndTime(wpInfoExamine.getEndTime());
                visitInfo.setScidType(wpInfoExamine.getScidType());
                //二次处理查询
                WpInfo wpInfo = new WpInfo();
                //二次处理
                wpInfo.setIsTransfer("2");
                wpInfo.setScidType(wpInfoExamine.getScidType());
                wpInfo.setBegainTime(wpInfoExamine.getBegainTime());
                wpInfo.setEndTime(wpInfoExamine.getEndTime());

                //承办单位办结查询
                WpHandleLog wpHandleLogSe = new WpHandleLog();

                wpHandleLogSe.setBegainTime(wpInfoExamine.getBegainTime());
                wpHandleLogSe.setEndTime(wpInfoExamine.getEndTime());
                wpHandleLogSe.setScidType(wpInfoExamine.getScidType());
                try {
                    visitInfo.setDeptLevel2(null);
                    String deptId = sysDept.getDeptId().toString();
                    WpInfoExamine wpInfoExamineCon = new WpInfoExamine();
                    List<WpHandleLog> handleLogs = wpHandleLogList.stream()
                            .filter(handleLog -> (deptId).equals(handleLog.getNextDepartment1()))
                            .collect(Collectors.toList());
                    if (handleLogs.size() == 0) {
    //                    continue;
                        return;
                    }
                    wpInfoExamineCon.setDeptLevel2Name(sysDept.getDeptName());
                    //派单总数---受理总数
                    Set<String> wpInfoCountWpids = handleLogs.stream()
                            .map(WpHandleLog::getWpid)
                            .collect(Collectors.toSet());


                    //TODO
                    WpBackInfo wpBackInfo = new WpBackInfo();
                    wpBackInfo.setBegainTime(wpInfo.getBegainTime());
                    wpBackInfo.setEndTime(wpInfo.getEndTime());
                    wpBackInfo.setDeptLevel2(String.valueOf(sysDept.getDeptId()));
                    wpBackInfo.setState("审核人收回工单");
                    wpBackInfo.setNextState("审核人处理");
                    List<String> recoverCountWpids = wpBackInfoMapper.selectRecoverCountWpids(wpBackInfo);

                    //总量
                    List<String> wpidsNew = new ArrayList<>();
                    if (recoverCountWpids.size()>0){
                        for (String recoverCountWpid : recoverCountWpids) {
                            WpHandleLog wpHandleLog = new WpHandleLog();
                            wpHandleLog.setWpid(recoverCountWpid);
                            wpHandleLog.setBegainTime(wpInfo.getBegainTime());
                            wpHandleLog.setEndTime(wpInfo.getEndTime());
                            List<WpHandleLog> wpHandleLogs = wpHandleLogMapper.selectWpHandleLogListByWpidAndTime(wpHandleLog);
                            WpHandleLog wpHandleLog1 = wpHandleLogs.stream().filter(dto -> "承办单位处理".equals(dto.getNextState()))
                                    .max(Comparator.comparing(WpHandleLog::getUpdateTime)).orElse(null);

                            WpHandleLog wpHandleLog2 = wpHandleLogs.stream().filter(dto -> "审核人收回工单".equals(dto.getLastState()))
                                    .max(Comparator.comparing(WpHandleLog::getUpdateTime)).orElse(null);
                            if (wpHandleLog1!=null&&wpHandleLog2!=null&&wpHandleLog2.getUpdateTime().compareTo(wpHandleLog1.getUpdateTime())>0){
                                wpidsNew.add(recoverCountWpid);
                            }
                            if (wpHandleLog1!=null&&wpHandleLog2!=null&&wpHandleLog2.getUpdateTime().compareTo(wpHandleLog1.getUpdateTime())<0&&StringUtils.isNotEmpty(wpHandleLog1.getNextDepartment1())
                                    &&!wpHandleLog1.getNextDepartment1().equals(sysDept.getDeptId().toString())){
                                wpidsNew.add(recoverCountWpid);
                            }
                        }
                    }

                    if (wpidsNew.size()>0){
                        wpInfoCountWpids.removeAll(wpidsNew);
                    }





                    List<String> timeoutUnsucesswpPoint = new ArrayList<>();


                    //TODO
                    for (String wpInfoCountWpid : wpInfoCountWpids) {

                        WpHandleLog wpHandleLogCon = new WpHandleLog();
                        wpHandleLogCon.setWpid(wpInfoCountWpid);
                        //工单轨迹记录
                        List<WpHandleLog> wpHandleLogs = wpHandleLogMapper.selectWpHandleLogList(wpHandleLogCon);
                        //承办单位处理
                        WpHandleLog logCon = wpHandleLogs.stream()
                                .filter(handleLog -> "承办单位处理".equals(handleLog.getNextState()))
                                .max(Comparator.comparing(WpHandleLog::getUpdateTime))
                                .orElse(null);

                        WpHandleLog logConVisit = wpHandleLogs.stream()
                                .filter(handleLog -> "工单回访".equals(handleLog.getNextState()))
                                .max(Comparator.comparing(WpHandleLog::getUpdateTime))
                                .orElse(null);
                        if (logCon == null) {
                            throw new BaseException("承办单位已完成工单数据异常");
                        }
                        Date updateTime = logCon.getUpdateTime();
                        Date time = wpInfoDeptService.checkOntime(updateTime, 2, dates);
                        if (logConVisit==null){
                            if (time.compareTo(new Date()) < 0) {
                                //2个工作日内没有完成，接收工单情况便会扣分
                                timeoutUnsucesswpPoint.add(wpInfoCountWpid);
                            }
                        }else {
                            if (time.compareTo(logConVisit.getUpdateTime()) < 0) {
                                //2个工作日内没有完成，接收工单情况便会扣分
                                timeoutUnsucesswpPoint.add(wpInfoCountWpid);
                            }
                        }


                    }

                    int acceptSize = wpInfoCountWpids.size();
                    wpInfoExamineCon.setAcceptedCount(acceptSize);

                    visitInfo.setDeptLevel2(deptId);
                    //流转工单编号集合
                    visitInfo.setWpIdsByFlowTime(wpInfoCountWpids);

                    //满意数
                    visitInfo.setIssatisfied("满意");
//                    List<String> satisCount =  wpVisitInfoMapper.selectDistentVisitWpid(visitInfo);
                    List<String> satisCount =  wpVisitInfoMapper.selectVisitByFlowTime(visitInfo);


                    //不满意数
                    visitInfo.setIssatisfied("不满意");
//                    List<String> unSatisCount =  wpVisitInfoMapper.selectDistentVisitWpid(visitInfo);
                    List<String> unSatisCount =  wpVisitInfoMapper.selectVisitByFlowTime(visitInfo);

                    //一般数
                    visitInfo.setIssatisfied("一般");
//                    List<String> kindCount =  wpVisitInfoMapper.selectDistentVisitWpid(visitInfo);
                    List<String> kindCount =  wpVisitInfoMapper.selectVisitByFlowTime(visitInfo);
                    //回访成功总数
                    int satisTotal = satisCount.size()+kindCount.size()+unSatisCount.size();
                    String satisPoint = this.getSatisPoint(satisTotal, satisCount.size(), kindCount.size(), unSatisCount.size());
                    //市民满意度得分
                    wpInfoExamineCon.setVisitSuccessCount(satisTotal);
                    wpInfoExamineCon.setSatisPoint(satisPoint);


                    wpInfo.setDeptLevel2(deptId);
                    // List<WpInfoDTO> wpInfoDTOS = wpInfoMapper.countWpInfoGroupByIsTransfer(wpInfo);

                    List<String> disposeCauseList = wpInfoMapper.selectDisposeCauseList(wpInfo);

                    List<String> disposeCauses = new ArrayList<>();
                    for (String s : disposeCauseList) {
                        String[] split = s.split(",");
                        List<String> strings = Arrays.asList(split);
                        if (strings.size()>0){
                            disposeCauses.addAll(strings);
                        }

                    }
                    List<String> replyPoints = disposeCauses.stream()
                            .filter("未明确结果"::equals).collect(Collectors.toList());

                    //二次处理原因：未答复市民数

                    //答复市民情况
                    String replyPoint = this.getReplyPoint(acceptSize, replyPoints.size());
                    wpInfoExamineCon.setReplyPoint(replyPoint);

                    List<String> fillwpPoints = disposeCauses.stream()
                            .filter("未明确依据和过程"::equals).collect(Collectors.toList());

                    //填写工单情况
                    String fillwpPoint = this.getfillwpPoint(acceptSize, fillwpPoints.size());
                    wpInfoExamineCon.setFillwpPoint(fillwpPoint);

                    //超时办结
                    wpHandleLogSe.setHfState("3");
                    wpHandleLogSe.setNextDepartment1(deptId);
                    //超时反馈(即超时完成数)
                    List<String> unfeedbackPoints = wpHandleLogMapper.selectwpidsCompleteDayByDeptLeftWpInfo(wpHandleLogSe);
                    //未完成数
                    wpHandleLogSe.setHfState(null);
                    //  List<String> unsucesswpPoint =  wpHandleLogMapper.selectUnCompletingCountWpidsByDeptLeftWpInfo(wpHandleLogSe);

                    String feedbackPoints = this.getFeedbackPoints(acceptSize, unfeedbackPoints.size());
                    wpInfoExamineCon.setFeedbackPoint(feedbackPoints);

//                    String sucesswpPoint = this.getSucesswpPoint(acceptSize, timeoutUnsucesswpPoint.size());
//                    wpInfoExamineCon.setSucesswpPoint(sucesswpPoint);
                    //接收工单情况 按统一打10分
                    wpInfoExamineCon.setSucesswpPoint("10.00");


                    String countPoint = this.getCountPoint(wpInfoExamineCon);

                    wpInfoExamineCon.setCountPoint(countPoint);

                    wpInfoExamines.add(wpInfoExamineCon);
                } catch (BaseException e) {
                    log.info("部门{}绩效考核报表报错:{}",sysDept.getDeptId(),e.toString());
                } finally {
                    log.info("部门{}绩效考核报表线程开启",sysDept.getDeptId());
                    //调用线程计数器-1
                    countDownLatch.countDown();
                }


            });

        }
        //唤醒主线程
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            log.info("报错：{}",e.toString());
        }

        return wpInfoExamines.stream().sorted(Comparator.comparing(WpInfoExamine::getAcceptedCount).reversed()).collect(Collectors.toList());
    }

    private String getCountPoint(WpInfoExamine wpInfoExamineCon) {
        if (StringUtils.isEmpty(wpInfoExamineCon.getSucesswpPoint())){
            wpInfoExamineCon.setSucesswpPoint("0");
        }
        if (StringUtils.isEmpty(wpInfoExamineCon.getSatisPoint())){
            wpInfoExamineCon.setSatisPoint("0");
        }
        if (StringUtils.isEmpty(wpInfoExamineCon.getReplyPoint())){
            wpInfoExamineCon.setReplyPoint("0");
        }
        if (StringUtils.isEmpty(wpInfoExamineCon.getFillwpPoint())){
            wpInfoExamineCon.setFillwpPoint("0");
        }
        if (StringUtils.isEmpty(wpInfoExamineCon.getFeedbackPoint())){
            wpInfoExamineCon.setFeedbackPoint("0");
        }
        Double aDouble = Double.valueOf(wpInfoExamineCon.getSucesswpPoint());
        Double bDouble = Double.valueOf(wpInfoExamineCon.getSatisPoint());
        Double cDouble = Double.valueOf(wpInfoExamineCon.getReplyPoint());
        Double dDouble = Double.valueOf(wpInfoExamineCon.getFillwpPoint());
        Double eDouble = Double.valueOf(wpInfoExamineCon.getFeedbackPoint());

        double v = aDouble + bDouble + cDouble + dDouble + eDouble;
        return String.format("%.2f", v);
    }

    /**
     * 接收工单分值
     *
     * @param acceptSize
     * @param timeoutUnsucesswpPointSize
     * @return
     */
    private String getSucesswpPoint(int acceptSize, int timeoutUnsucesswpPointSize) {
        if (acceptSize==0){
            return "0.00";
        }
        double v = (1 - (double) timeoutUnsucesswpPointSize / (double) acceptSize) * 10;
        return String.format("%.2f", v);
    }

    /**
     * 反馈分值计算
     *
     * @param acceptSize
     * @param unfeedbackSize
     * @return
     */
    private String getFeedbackPoints(int acceptSize, int unfeedbackSize) {
        if (acceptSize==0){
            return "0.00";
        }
        //(1-超时反馈工单数/受理工单总数)*10
        double v = (1 - (double) unfeedbackSize / (double) acceptSize) * 10;
        return String.format("%.2f", v);
    }


    /**
     * 满意度计算
     *
     * @param visitSize
     * @param satisSize
     * @param kindSize
     * @param unSatisSize
     * @return
     */
    public String getSatisPoint(int visitSize, int satisSize, int kindSize, int unSatisSize) {

        if (visitSize==0){
            return "0.00";
        }
        //(满意度*1+一般数*0.6+不满意*0)/总回访数*30
        double v = ((double) satisSize + (double) kindSize * 0.6) / (double) visitSize;
        //返回结果保留两位小数  市民满意度情况  15分
        return String.format("%.2f", v * 15);


    }

    /**
     * 答复市民计算
     *
     * @param acceptSize
     * @param replyPointSize
     * @return
     */
    public String getReplyPoint(int acceptSize, int replyPointSize) {

        if (acceptSize==0){
            return "0.00";
        }
        double v = (1 - (double) replyPointSize / (double) acceptSize) * 25;
        return String.format("%.2f", v);
    }

    /**
     * 答复市民计算
     *
     * @param acceptSize
     * @param fillwpPointSize
     * @return
     */
    public String getfillwpPoint(int acceptSize, int fillwpPointSize) {
        if (acceptSize==0){
            return "0.00";
        }
        double v = (1 - (double) fillwpPointSize / (double) acceptSize) * 20;
        return String.format("%.2f", v);
    }

}
